#include "stdafx.h"
#include "Mesh.h"

#include "MeshPart.h"
#include "VertexStream.h"

namespace WindGE
{
	Mesh::Mesh()
	{
	}

	Mesh::~Mesh()
	{
	}

	void Mesh::add(MeshPartPtr meshPart)
	{
		mesh_parts_.push_back(meshPart);
	}

	bool Mesh::at(unsigned int index, MeshPartPtr& meshPart) const
	{
		if (index < 0 || index >= mesh_parts_.size()) return false;

		meshPart = mesh_parts_[index];
		return true;
	}

	bool Mesh::save(const std::string& fileName)
	{
		std::ofstream outFile(fileName, std::ios::binary);
		if (!outFile) return false;

		if (!save(outFile)) return false;

		outFile.close();

		return true;
	}

	bool Mesh::save(std::ostream& outFile)
	{
		//write size
		unsigned int size = mesh_parts_.size();
		outFile.write((char*)&size, sizeof(unsigned int));

		for (unsigned int i = 0; i < size; ++i)
		{
			if (!mesh_parts_[i]->save(outFile)) return false;
		}

		return true;
	}

	bool Mesh::load(const std::string& fileName)
	{
		std::ifstream inFile(fileName, std::ios::binary);
		if (!inFile) return false;

		if (!load(inFile)) return false;

		inFile.close();

		return true;
	}

	bool Mesh::load(std::istream& inFile)
	{
		unsigned int size = 0;
		inFile.read((char*)&size, sizeof(unsigned int));

		for (unsigned int i = 0; i < size; ++i)
		{
			MeshPartPtr meshPart = std::make_shared<MeshPart>();
			if (!meshPart->load(inFile)) return false;
			
			add(meshPart);
		}

		return true;
	}

	unsigned int Mesh::vertex_stream_size(const std::string& vsName) const
	{
		unsigned int size = 0;
		for_each(mesh_parts_.begin(), mesh_parts_.end(), [&size, vsName](MeshPartPtr meshPart)
		{
			VertexStreamPtr vs = nullptr;
			if (meshPart->find(vsName, vs))
			{
				size += vs->stride()*vs->size();
			}
		});
		return size;
	}

}//end namespace WindGE

